package com.fingard.dsp.bank.directbank.hsbc01;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingleBat;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingleBat;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingleBat;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpReceiver;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.ForeignBankUtil;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * @author XueJy on 2018/9/13.
 * @version 1.0
 */
public class HSBC01SinglePay extends HSBC01Base implements ISinglePay {
    public static ForeignBankUtil foreignBankHelper=null;

    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        //保险
        if ("0".equals(this.getBankConfig().getValueAsString("channelFalg"))) {
            //指令代码
            XmlTextWriter xmlWriterMsg = new XmlTextWriter();
            String bakUpPath = getCommonDataFileDirectory(new Date(), "HSHBC") + File.separator + "singlePay";
            writeRecCommonHeader(xmlWriterMsg, p_req1908);
            writeSingePayBodyParams(xmlWriterMsg, p_req1908);
            writeEnds(xmlWriterMsg);
            WriteBankLogStep2(xmlWriterMsg.toXmlString());
            String fileName = p_req1908.singleDetail.askNumber + ".xml";
            String sendFilePath = bakUpPath + File.separator + fileName;
            FileHelper.writeFile(sendFilePath, xmlWriterMsg.toXmlString(), getCharset());
            FtpReceiver ftpReceiver = sendToBank(sendFilePath, fileName, EnumTransMode.SinglePayForHF.getValue());
            //FtpReceiver ftpReceiver = sendToBank(sendFilePath, fileName);
            detail.respCode = "0";
            detail.reqSeqID = p_req1908.singleDetail.askNumber;
            if (ftpReceiver.isCompleted) {
                detail.respInfo = "支付文件上传成功";
                detail.transState = "Uploaded";
                detail.payInfoCode = "Uploaded";
            } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                detail.respInfo = "支付文件上传失败";
                detail.transState = "Upload Failed";
                detail.payInfoCode = "Upload Failed";
            } else {
                detail.respCode = "-1";
                detail.respInfo = ftpReceiver.connMsg;
            }
            retAts.writeRetDetail(detail);
            return retAts;
        } else {//企金
            if("1".equals(this.getBankConfig().getValueAsString("payTypeIsRmb"))){
                //拼接付款请求报文
                XmlTextWriter xmlWriter = new XmlTextWriter();
                writeCommonHeader(xmlWriter);
                writeFileContent(xmlWriter,p_req1908);
                //生成付款文件目录
                String payDate=DateHelper.convertD10toD8(p_req1908.singleDetail.payDate);
                String payFilePath = getBankConfig().getValueAsString("PayFilePath")+ File.separator +payDate +File.separator
                        +"CN"+payDate.substring(2,8)+"_"+"PP"+"_v3_"+p_req1908.singleDetail.askNumber+".txt";
                WriteBankLogLn("请求银行的报文："+xmlWriter.toXmlString());
                foreignBankHelper=new ForeignBankUtil(getBankConfig(),bankFront,getSbLog(),getCharset());
                //生成付款文件并上传
                String[] bankResult=new String[]{"",""};
                if(StringHelper.hasAnyChar(getBankConfig().getValueAsString("transType"))
                        && getBankConfig().getValueAsString("transType").equals("true")) {
                    //付款文件需要加密加签
                    bankResult=foreignBankHelper.uploadPayFileIsEncrypt(xmlWriter.toXmlString(),payFilePath,getCharset(),"sftpserverHK");
                }else {
                    //付款文件不需要加密
                    bankResult=foreignBankHelper.uploadPayFile(xmlWriter.toXmlString(),payFilePath,getCharset(),"sftpserverHK");
                }
                //响应到ats
                detail.respCode = "0";
                detail.respInfo = bankResult[1];
                detail.transState = bankResult[0];
                detail.payInfoCode = detail.transState;
                detail.reqSeqID=p_req1908.singleDetail.askNumber;
                retAts.writeRetDetail(detail);
                return retAts;
            }else {
                detail.respCode = "";
                String nReqSeqID = p_req1908.singleDetail.askNumber;
                String uniqueFileCode = nReqSeqID;
                if (detail.respCode.length() == 0) {
                    StringBuilder sbPay = new StringBuilder();
                    int recordCount = 1;
                    //拼接报文体
                    StringBuilder context = PaymentXmlToFileBody(p_req1908);
                    sbPay.append(context);
                    recordCount = recordCount + 2;//+2/次
                    //追加header
                    StringBuilder header = PaymentXMLToFileHeader(uniqueFileCode, recordCount);
                    sbPay.insert(0, header.toString());
                    String paydate2 = p_req1908.singleDetail.payDate.replaceAll("-", "");
                    String paymentFileName = "CN" + " " + "RTGS_iFile_PP" + "_" + p_req1908.singleDetail.askNumber + ".txt";
                    String fullName = getBankConfig().getValueAsString("PayFilePath") + File.separator + paydate2 + File.separator + paymentFileName;
                    //写入文件
                    if (!exportContentToFile(sbPay.toString(), fullName)) {
                        detail.transState = "E1101";
                        detail.payInfoCode = "E1101";
                        detail.respCode = "0";
                        detail.respInfo = "生成支付文件失败";
                        retAts.writeRetDetail(detail);
                        return retAts;
                    }
                    //true 加密   false 不加密
                    if ("true".equals(getBankConfig().getValueAsString("EncryptFlag"))) {
                        //对支付文件加密，并生成加密文件
                    }
                    //上传文件
                    if (!uploadFileIsQJ(fullName)) {
                        detail.transState = "E1103";
                        detail.payInfoCode = "E1103";
                        detail.respCode = "0";
                        detail.respInfo = "上传文件失败";
                        retAts.writeRetDetail(detail);
                        return retAts;
                    }
                    detail.respCode = "0";
                    detail.respInfo = "发送文件成功";
                    detail.transState = "Vaild";
                    detail.payInfoCode = "Vaild";
                    retAts.writeRetDetail(detail);
                    return retAts;
                }
            }
        }
        return retAts;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        //保险
        if ("0".equals(this.getBankConfig().getValueAsString("channelFalg"))) {
            String actNo = p_req1944.payAct;
            String askNumber = p_req1944.askNumber;
            RetAtsSglDetail retDetail = new RetAtsSglDetail();
            retDetail.reqSeqID = p_req1944.askNumber;
            //生产用
            FtpReceiver ftpReceiver = downloadFile();
            //测试用
//            FtpReceiver ftpReceiver = downFromHF();

            if (ftpReceiver != null) {
                if (ConnState.FAIL.equals(ftpReceiver.connState) || (!ftpReceiver.isCompleted && !"file not exists".equals(ftpReceiver.connState))) {
                    retDetail.respInfo = ftpReceiver.connState + "+" + ftpReceiver.connMsg;
                    retDetail.respCode = "-1";
                    retAts.writeRetDetail(retDetail);
                    return retAts;
                }
            }
            String ackPath = getReceivePath(EnumDirType.SingleAck.getValue(), p_req1944.getBgnDateTime());
//            String ackPath = getReceivePath("singleack", p_req1944.getBgnDateTime());
            List<String> filenames = getDirectoryAllFileName(ackPath);
            String batchNo = p_req1944.askNumber;
            //是否有ack文件
            boolean ackFlag = false;
            //是否被拒绝了
            boolean refusedFlag = false;
            //是否有结果
            boolean hasResult = false;
            String refusedMessage = "";

            for (String filename : filenames) {
                String contain = "";
                synchronized (this) {
                    //读取文件内容
                    contain = FileHelper.readFileText(ackPath + File.separator + filename, "UTF-8");
                }
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(contain, tmpSbMsg);
                //ack解析
                if (tmpBkReader != null) {
                    String orgnlMsgId = tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/OrgnlMsgId");
                    if (orgnlMsgId.equals(batchNo)) {
                        ackFlag = true;
                        WriteBankLogLn("单笔付款ACK文件内容:+\n" + contain);
                        String grpSts = tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/GrpSts");
                        // RJCT    ACCP
                        if ("ACCP".equals(grpSts)) {
                            retDetail.respCode = "0";
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(Format.Date10Format.parse(p_req1944.bgnDate.substring(0, 10)));
                            //时间
                            long nowTimeMillis = System.currentTimeMillis();
                            do {
                                String datePath = getReceivePath(EnumDirType.MT942.getValue(), cal.getTime());
//                                String datePath = getReceivePath("MT942", cal.getTime());
                                //被筛选文件
                                List<String> allDetailsFileNames = getDirectoryAllFileName(datePath);
                                //筛选结果文件
                                List<String> detailsFileNames = new ArrayList<String>();
                                for (String fileName : allDetailsFileNames) {
                                    //MT942CN.EJ321.071910135852.088251418011.TXT
                                    if (fileName.split("\\.")[3].equals(actNo)) {
                                        detailsFileNames.add(fileName);
                                    }
                                }
                                for (String fileName : detailsFileNames) {
                                    try {
                                        String alltext = FileHelper.readFileText(getTrimPath(datePath) + File.separator + fileName, getCharset());
                                        //对单个文件进行解析查找对应的账号明细信息 //"H", 明细头记录拆分符
                                        String[] sArray1 = alltext.split(":25:");
                                        if (sArray1.length > 1 && sArray1[1].startsWith(actNo)) {
                                            String[] txns = sArray1[1].split(":61:");
                                            if (txns.length > 1) {
                                                for (int i = 1; i < txns.length; i++) {
                                                    String msg61 = txns[i];
                                                    String returnAsk = msg61.substring(msg61.indexOf(",") + 7, msg61.indexOf("//")).trim();
                                                    if (askNumber.equals(returnAsk)) {
                                                        retDetail.reqSeqID = returnAsk;
                                                        retDetail.respInfo = "交易成功";
                                                        retDetail.respCode = "0";
                                                        retDetail.transState = "S0000";
                                                        retDetail.payInfoCode = "S0000";
                                                        retAts.writeRetDetail(retDetail);
                                                        return retAts;
                                                    }
                                                }

                                            }
                                        }
                                    } catch (Exception ex) {
                                        WriteBankLogLn("解析：" + fileName + " 文件异常：" + ex);
                                    }
                                }

                                cal.add(Calendar.DAY_OF_YEAR, 1);
                                //查询小于当前时间,大于发送时间
                            } while (!hasResult && cal.getTimeInMillis() < nowTimeMillis);
                            //支付失败 不会产生报告,查询两天没有结果 则直接失败
                            if ("4".equals(p_req1944.payState)) {
                                p_req1944.payState = "5";
                            }
                            if (canBeNotExist(p_req1944, retDetail, 14400)) {
                                retDetail.respCode = "0";
                                retDetail.respInfo = "查询无记录";
                                retDetail.transState = PaymentState.FAIL_Payment;
                                retDetail.payInfoCode = "查询无记录";
                                retAts.writeRetDetail(retDetail);
                                return retAts;
                            } else {
                                retAts.writeRetDetail(retDetail);
                                return retAts;
                            }
                        } else {
                            //拒绝 支付失败  可能存在重复支付后再次发起的拒绝. 要看完所有ACK 若有 则Accep  则成功
                            refusedFlag = true;
                            refusedMessage = tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/StsRsnInf/AddtlInf");
                        }
                    }
                }
            }
            //如果找不到ACK文件则再次发送
            if (!ackFlag) {

                retDetail.respCode = "-1";
                retDetail.respInfo = "暂时无法查询到ACK文件,请稍后再试";
                retAts.writeRetDetail(retDetail);
                return retAts;

            } else if (refusedFlag) {
                retDetail.respCode = "0";
                retDetail.respInfo = refusedMessage;
                retDetail.transState = PaymentState.FAIL_Payment;
                retDetail.payInfoCode = refusedMessage;
                retAts.writeRetDetail(retDetail);
                return retAts;
            }

        } else {//企金
            if("1".equals(this.getBankConfig().getValueAsString("payStatusIsRmb"))){
                RetAtsSglDetail retDetail = null;
                //处理ack文件或者MT文件，获取支付状态  result={"付款状态码","响应信息"}
                foreignBankHelper=new ForeignBankUtil(getBankConfig(),bankFront,getSbLog(),getCharset());
                String[] result=foreignBankHelper.getPayStatus(p_req1944.askNumber,p_req1944.getBgnDateTime());
                if(result.length==2 && StringHelper.hasAnyChar(result[0])){
                    retDetail = new RetAtsSglDetail();
                    retDetail.respCode = "0";
                    retDetail.respInfo=result[1];
                    retDetail.transState = result[0];
                    retDetail.payInfoCode = retDetail.transState;
                    retDetail.reqSeqID=p_req1944.askNumber;
                }
                retAts.writeRetDetail(retDetail);
                return retAts;
            }else {
                /**
                 * 判断支付状态：日终文件MT940是否生成，如果生成则查找支付流水号是否存在匹配流水明细。有则成功，无则失败；
                 *               如果日终未生成，判断日间文件MT942是否生成，如果生成则查找支付流水号是否存在匹配流水明细。有则成功，无则处理中；
                 *               如果日间未生成，则为处理中。
                 */
                RetAtsSglDetail retDetail = null;
                //获取支付时间
                String payDate = Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1944.bgnDate));
                //判断MT940文件是否存在
                String dealedFile = getBankConfig().getValueAsString("DealedPath") + File.separator + payDate +
                        File.separator + "MT940" + File.separator + p_req1944.payAct + "_7516.txt";
                if (FileHelper.existFile(dealedFile)) {
                    WriteBankLogLn("文件" + dealedFile + "存在,当天日终文件已生成");
                    InputStreamReader isr = new InputStreamReader(new FileInputStream(dealedFile), "UTF-8");
                    BufferedReader reader = new BufferedReader(isr);
                    String readLine = "";
                    Boolean flag = false;//交易状态
                    while ((readLine = reader.readLine()) != null) {
                        String[] transDetail = readLine.split("\\|");
                        String cdFlag = transDetail[6].trim();//借贷标识
                        String amt = transDetail[5].trim();//交易金额
                        String seqId = transDetail[12].trim();//支付流水号
                        //如果支付流水号在对应MT940明细中有流水产生，则说明支付成功
                        if (p_req1944.askNumber.equals(seqId) && "D".equals(cdFlag) && !"".equals(amt)) {
                            retDetail = new RetAtsSglDetail();
                            retDetail.respCode = "0";
                            retDetail.respInfo = "支付成功";
                            retDetail.payInfoCode = "0";
                            retDetail.reqSeqID = seqId;
                            retDetail.transState = "0";
                            retDetail.transAmt = "";
                            flag = true;
                        }
                    }
                    //否则说明支付失败
                    if (!flag) {
                        retDetail = new RetAtsSglDetail();
                        retDetail.respCode = "0";
                        retDetail.respInfo = "支付失败";
                        retDetail.payInfoCode = "2";
                        retDetail.reqSeqID = p_req1944.askNumber;
                        retDetail.transState = "2";
                        retDetail.transAmt = "";
                    }
                } else {
                    WriteBankLogLn("文件" + dealedFile + "不存在，当天日终文件未生成");
                    String dealedPath = getBankConfig().getValueAsString("DealedPath") + File.separator + payDate +
                            File.separator + "MT942" + File.separator + p_req1944.payAct + "_7515.txt";
                    if (FileHelper.existFile(dealedPath)) {
                        WriteBankLogLn("文件" + dealedPath + "存在，当天日间文件已开始接收");
                        InputStreamReader isr = new InputStreamReader(new FileInputStream(dealedPath), "UTF-8");
                        BufferedReader reader = new BufferedReader(isr);
                        String readLine = "";
                        Boolean flag = false;//交易状态
                        while ((readLine = reader.readLine()) != null) {
                            String[] transDetail = readLine.split("\\|");
                            String cdFlag = transDetail[6].trim();//借贷标识
                            String amt = transDetail[5].trim();//交易金额
                            String seqId = transDetail[12].trim();//支付流水号
                            //如果支付流水号在对应MT942明细中有流水产生，则说明支付成功
                            if (p_req1944.askNumber.equals(seqId) && "D".equals(cdFlag) && !"".equals(amt)) {
                                retDetail = new RetAtsSglDetail();
                                retDetail.respCode = "0";
                                retDetail.respInfo = "支付成功";
                                retDetail.payInfoCode = "0";
                                retDetail.reqSeqID = seqId;
                                retDetail.transState = "0";
                                retDetail.transAmt = "";
                                flag = true;
                            }
                        }
                        //否则说明还在处理中
                        if (!flag) {
                            retDetail = new RetAtsSglDetail();
                            retDetail.respCode = "0";
                            retDetail.respInfo = "支付处理中";
                            retDetail.payInfoCode = "1";
                            retDetail.reqSeqID = p_req1944.askNumber;
                            retDetail.transState = "1";
                            retDetail.transAmt = "";
                        }
                    } else {
                        WriteBankLogLn("文件" + dealedPath + "不存在，当天日间文件暂未接收");
                        retDetail = new RetAtsSglDetail();
                        retDetail.respCode = "0";
                        retDetail.respInfo = "支付处理中";
                        retDetail.payInfoCode = "1";
                        retDetail.reqSeqID = p_req1944.askNumber;
                        retDetail.transState = "1";
                        retDetail.transAmt = "";
                    }
                }
                retAts.writeRetDetail(retDetail);
            }
        }
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
